﻿using System;
using System.IO;
using System.Net;
using System.Text;

namespace MSA.SocialNetworking
{
    class original_msa_twitter
    {
        #region Declarations
        private CredentialCache TwitterCreds = new CredentialCache();
        protected const string TwitterAPIbaseURL = "http://twitter.com/{0}/{1}.{3}";
        protected const string TwitterAPIuserURL = "http://twitter.com/{0}/{1}/{2}.{3}";
        #endregion

        #region API Calls
        private enum TwitterRequest
        {
            GET, POST
        }
        private enum TwitterObject
        {
            account, followers, friends, statuses, users, direct_messages, friendships, favorites, notifications, blocks
        }
        private enum TwitterMethods
        {
            verify_credentials, end_session, update_delivery_device, update_profile_colors,
            update_profile_image, update_profile_background_image, rate_limit_status, update_profile, ids,
            public_timeline, friends_timeline, user_timeline, show, update, replies, destroy, friends,
            followers, direct_messages, sent, n_ew, create, exists, favorites, follow, leave, test
        }
        private enum TwitterResponseFormat
        {
            xml, //The only format implemented in this class.
            json,
            rss,
            atom
        }
        #endregion

        public string VerifyCredentials(string _username, string _password)
        {
            Uri URL = new Uri(getURL(TwitterObject.account.ToString(), TwitterMethods.verify_credentials.ToString(), null, TwitterResponseFormat.xml.ToString()));
            if (SetCredentials(_username, _password))
            {
                string response = SendRequest(URL, TwitterCreds, TwitterRequest.GET.ToString());
                //return (Boolean)ParseXML(response);
                return response;
            }
            else { return "An Error Occured"; }
        }

        public Boolean SetCredentials(string _username, string _password)
        {
            try
            {
				TwitterCreds.Add(new Uri("http://twitter.com"), "Basic", new NetworkCredential(_username, _password));
            }
            catch(ArgumentException)
            {
				if (_username == "" || _password == "")
				{
					return false;
				}
				else
				{
					TwitterCreds.Remove(new Uri("http://twitter.com"), "Basic");
					TwitterCreds.Add(new Uri("http://twitter.com"), "Basic", new NetworkCredential(_username, _password));	
				} 
            }
            return true;
        }

        public string GetFollowers(string _user)
        {
            Uri URL = new Uri(getURL(TwitterObject.followers.ToString(), TwitterMethods.ids.ToString(), _user, TwitterResponseFormat.xml.ToString()));
            string response = SendRequest(URL, TwitterCreds, TwitterRequest.GET.ToString());
            return response;
        }

        public string GetFollowersStatus(string _user)
        {
            return GetFollowersStatus(_user, 1);
        }
        
        public string GetFollowersStatus(string _user, int _page)
        {
            Uri URL = new Uri(getURL(TwitterObject.statuses.ToString(), TwitterMethods.followers.ToString(), _user, string.Format("{0}?page={1}", TwitterResponseFormat.xml.ToString(), _page)));
            string response = SendRequest(URL, TwitterCreds, TwitterRequest.GET.ToString());
            return response;
        }

        public string GetFriends(string _user)
        {
            Uri URL = new Uri(getURL(TwitterObject.friends.ToString(), TwitterMethods.ids.ToString(), _user, TwitterResponseFormat.xml.ToString()));
            string response = SendRequest(URL, TwitterCreds, TwitterRequest.GET.ToString());
            return response;
        }

        public string GetFriendsStatus(string _user)
        {
            return GetFriendsStatus(_user, 1);
        }

        public string GetFriendsStatus(string _user, int _page)
        {
            Uri URL = new Uri(getURL(TwitterObject.statuses.ToString(), TwitterMethods.friends.ToString(), _user, string.Format("{0}?page={1}",TwitterResponseFormat.xml.ToString(), _page)));
            string response = SendRequest(URL, TwitterCreds, TwitterRequest.GET.ToString());
            return response;
        }

        public string GetReplies()
        {
            return GetReplies("1","1");
        }

        public string GetReplies(string _id)
        {
            return GetReplies(_id, "1");
        }

        public string GetReplies(string _id, string _page)
        {
            Uri URL = new Uri(getURL(TwitterObject.statuses.ToString(), TwitterMethods.replies.ToString(), null, string.Format("{0}?since_id={1}&page={2}", TwitterResponseFormat.xml.ToString(), _id, _page)));
            string response = SendRequest(URL, TwitterCreds, TwitterRequest.GET.ToString());
            return response;
        }


        public string GetUpdates()
        {
            return GetUpdates("1");
        }

        public string GetUpdates(string _id)
        {
            Uri URL = new Uri(getURL(TwitterObject.statuses.ToString(), TwitterMethods.user_timeline.ToString(), null, string.Format("{0}?since_id={1}", TwitterResponseFormat.xml.ToString(), _id)));
            string response = SendRequest(URL, TwitterCreds, TwitterRequest.GET.ToString());
            return response;
        }

        public string Update(string _announcement, string _source)
        {
            Uri sURL = new Uri(getURL(TwitterObject.statuses.ToString(), TwitterMethods.update.ToString(), null, TwitterResponseFormat.xml.ToString()));
            return SendRequest(sURL, TwitterCreds, TwitterRequest.POST.ToString(), string.Format("status={0}&source={1}", _announcement, _source));
        }


        #region Private methods

        private object ParseXML(string response)
        {
            throw new NotImplementedException();
        }

        private string getURL(string _object, string _method, string _user, string _format)
        {
            if (_user == null)
            {
                return string.Format(TwitterAPIbaseURL, _object, _method, _user, _format);
            }
            else
            {
                return string.Format(TwitterAPIuserURL, _object, _method, _user, _format);
            }
        }

        private string SendRequest(Uri _URL, CredentialCache _creds, string _type)
        {
            return SendRequest(_URL, _creds, _type, null);
        }

        private string SendRequest(Uri _URL, CredentialCache _creds, string _type, string _message)
        {
            string responseXml = String.Empty;
            switch (_type)
            {
                case "GET":
                    WebClient wCli = new WebClient();
                    if (_creds != null)
                    {
                        wCli.Credentials = _creds;
                    }
                    try
                    {
                        using (Stream str = wCli.OpenRead(_URL))
                        {
                            using (StreamReader reader = new StreamReader(str))
                            {
                                responseXml = reader.ReadToEnd();
                            }
                        }
                    }
                    catch (WebException ex)
                    {
                        if (ex.Response is HttpWebResponse)
                        {
                            if ((ex.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotFound)
                            {
                                return null;
                            }
                        }
                        throw ex;
                    }
                    TwitterCreds.Remove(new Uri("http://twitter.com"), "Basic");
                    wCli.Dispose();
                    return responseXml;

                case "POST":
                    HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create(_URL);
                    wReq.Credentials = _creds;
                    wReq.Method = _type;
                    wReq.ContentType = "application/x-www-form-urlencoded";
                    wReq.Timeout = 100000;                    
                    byte[] bytes = Encoding.ASCII.GetBytes(_message);
                    wReq.ServicePoint.Expect100Continue = false;
                    wReq.ContentLength = bytes.Length;
                    using (Stream str = wReq.GetRequestStream())
                    {
                        str.Write(bytes, 0, bytes.Length);
                        str.Close();
                    }

                    using (WebResponse wResp = wReq.GetResponse())
                    {
                        using (StreamReader reader = new StreamReader(wResp.GetResponseStream()))
                        {
                            responseXml = reader.ReadToEnd();
                        }
                        wReq = null;
                        wResp.Close();
                    }
                    TwitterCreds.Remove(new Uri("http://twitter.com"), "Basic");
               
                    return responseXml;
                default:
                    //No Action
                    break;
            }
            TwitterCreds.Remove(new Uri("http://twitter.com"), "Basic");

            return "";
        }

        private string ErrorReporter()
        {
            return null;
        }
        #endregion
    }
}
